/*
 * @brief PLL test (implementation file)
 *
 * @note
 * Copyright(C) NXP Semiconductors, 2015
 * All rights reserved.
 *
 * @par
 * Software that is described herein is for illustrative purposes only
 * which provides customers with programming information regarding the
 * LPC products.  This software is supplied "AS IS" without any warranties of
 * any kind, and NXP Semiconductors and its licensor disclaim any and
 * all warranties, express or implied, including all implied warranties of
 * merchantability, fitness for a particular purpose and non-infringement of
 * intellectual property rights.  NXP Semiconductors assumes no responsibility
 * or liability for the use of the software, conveys no license or rights under any
 * patent, copyright, mask work right, or any other intellectual property rights in
 * or to any products. NXP Semiconductors reserves the right to make changes
 * in the software without notification. NXP Semiconductors also makes no
 * representation or warranty that such application will be suitable for the
 * specified use without further testing or modification.
 *
 * @par
 * Permission to use, copy, modify, and distribute this software and its
 * documentation is hereby granted, under NXP Semiconductors' and its
 * licensor's relevant copyrights in the software, without fee, provided that it
 * is used in conjunction with NXP Semiconductors microcontrollers.  This
 * copyright, permission, and disclaimer notice must appear in all copies of
 * this code.
 */

#define NVALMAX						(0x100)
#define PVALMAX						(0x20)
#define MVALMAX						(0x8000)

/* SYS PLL related bit fields */
#define SYS_PLL_SELR(d)				(((d) & 0xf) << 0)		/*!< Bandwidth select R value */
#define SYS_PLL_SELI(d)				(((d) & 0x3f) << 4)		/*!< Bandwidth select I value */
#define SYS_PLL_SELP(d)				(((d) & 0x1f) << 10)	/*!< Bandwidth select P value */
#define SYS_PLL_BYPASS				(1 << 15)				/*!< Enable PLL bypass */
#define SYS_PLL_BYPASSCCODIV2		(1 << 16)				/*!< Enable bypass of extra divider by 2 */
#define SYS_PLL_UPLIMOFF			(1 << 17)				/*!< Enable spread spectrum/fractional mode */
#define SYS_PLL_BANDSEL				(1 << 18)				/*!< Enable MDEC control */
#define SYS_PLL_DIRECTI				(1 << 19)				/*!< PLL0 direct input enable */
#define SYS_PLL_DIRECTO				(1 << 20)				/*!< PLL0 direct output enable */

// #define FRAC_BITS_SELI			(8)		// For retaining fractions in divisions
#define PLL_SSCG0_MDEC_VAL_P	(0)			// MDEC is in bits	16 downto 0
#define PLL_SSCG0_MDEC_VAL_M	(0x1FFFFUL << PLL_SSCG0_MDEC_VAL_P)		// NDEC is in bits	9 downto 0
#define PLL_NDEC_VAL_P			(0)			// NDEC is in bits	9:0
#define PLL_NDEC_VAL_M			(0x3FFUL << PLL_NDEC_VAL_P)
#define PLL_PDEC_VAL_P			(0)			// PDEC is in bits 6:0
#define PLL_PDEC_VAL_M			(0x3FFUL << PLL_PDEC_VAL_P)

#define PLL_MIN_CCO_FREQ_MHZ	(75000000)
#define PLL_MAX_CCO_FREQ_MHZ	(150000000)
#define PLL_LOWER_IN_LIMIT		(4000)				/*!< Minimum PLL input rate */
#define PLL_MIN_IN_SSMODE		(2000000)
#define PLL_MAX_IN_SSMODE		(4000000)

// Middle of the range values for spread-spectrum
#define PLL_SSCG_MF_FREQ_VALUE								 4
#define PLL_SSCG_MC_COMP_VALUE								 2
#define PLL_SSCG_MR_DEPTH_VALUE								 4
#define PLL_SSCG_DITHER_VALUE								 0

// pll SYSPLLCTRL Bits
#define SYSCON_SYSPLLCTRL_SELR_P								0
#define SYSCON_SYSPLLCTRL_SELR_M								(0xFUL << SYSCON_SYSPLLCTRL_SELR_P)
#define SYSCON_SYSPLLCTRL_SELI_P								4
#define SYSCON_SYSPLLCTRL_SELI_M								(0x3FUL << SYSCON_SYSPLLCTRL_SELI_P)
#define SYSCON_SYSPLLCTRL_SELP_P								10
#define SYSCON_SYSPLLCTRL_SELP_M								(0x1FUL << SYSCON_SYSPLLCTRL_SELP_P)
#define SYSCON_SYSPLLCTRL_BYPASS_P							15		// sys_pll150_ctrl
#define SYSCON_SYSPLLCTRL_BYPASS								(1UL << SYSCON_SYSPLLCTRL_BYPASS_P)
#define SYSCON_SYSPLLCTRL_BYPASS_FBDIV2_P				16
#define SYSCON_SYSPLLCTRL_BYPASS_FBDIV2					(1UL << SYSCON_SYSPLLCTRL_BYPASS_FBDIV2_P)
#define SYSCON_SYSPLLCTRL_UPLIMOFF_P						17
#define SYSCON_SYSPLLCTRL_UPLIMOFF							(1UL << SYSCON_SYSPLLCTRL_UPLIMOFF_P)
#define SYSCON_SYSPLLCTRL_BANDSEL_SSCGREG_N_P		18
#define SYSCON_SYSPLLCTRL_BANDSEL_SSCGREG_N			(1UL << SYSCON_SYSPLLCTRL_BANDSEL_SSCGREG_N_P)
#define SYSCON_SYSPLLCTRL_DIRECTI_P							19
#define SYSCON_SYSPLLCTRL_DIRECTI								(1UL << SYSCON_SYSPLLCTRL_DIRECTI_P)
#define SYSCON_SYSPLLCTRL_DIRECTO_P							20
#define SYSCON_SYSPLLCTRL_DIRECTO								(1UL << SYSCON_SYSPLLCTRL_DIRECTO_P)

#define SYSCON_SYSPLLSTAT_LOCK_P								0
#define SYSCON_SYSPLLSTAT_LOCK								(1UL << SYSCON_SYSPLLSTAT_LOCK_P)

#define PLL_CTRL_BYPASS_P												   15		// sys_pll150_ctrl
#define PLL_CTRL_BYPASS_FBDIV2_P										   16
#define PLL_CTRL_UPLIMOFF_P												   17
#define PLL_CTRL_BANDSEL_SSCGREG_N_P									   18
#define PLL_CTRL_DIRECTI_P												   19
#define PLL_CTRL_DIRECTO_P												   20

#define PLL_CTRL_BYPASS													   (1 << PLL_CTRL_BYPASS_P)
#define PLL_CTRL_DIRECTI												   (1 << PLL_CTRL_DIRECTI_P)
#define PLL_CTRL_DIRECTO												   (1 << PLL_CTRL_DIRECTO_P)
#define PLL_CTRL_UPLIMOFF												   (1 << PLL_CTRL_UPLIMOFF_P)
#define PLL_CTRL_BANDSEL_SSCGREG_N										   (1 << PLL_CTRL_BANDSEL_SSCGREG_N_P)
#define PLL_CTRL_BYPASS_FBDIV2											   (1 << PLL_CTRL_BYPASS_FBDIV2_P)

// SSCG control[0]
// #define PLL_SSCG0_MDEC_VAL_P												   0	// MDEC is in bits	16 downto 0
#define PLL_SSCG0_MREQ_P												   17
#define PLL_SSCG0_SEL_EXT_SSCG_N_P										   18
#define PLL_SSCG0_SEL_EXT_SSCG_N										   (1 << PLL_SSCG0_SEL_EXT_SSCG_N_P)
#define PLL_SSCG0_MREQ													   (1 << PLL_SSCG0_MREQ_P)

// SSCG control[1]
#define PLL_SSCG1_MD_REQ_P												   19
#define PLL_SSCG1_MOD_PD_SSCGCLK_N_P									   28
#define PLL_SSCG1_DITHER_P												   29
#define PLL_SSCG1_MOD_PD_SSCGCLK_N										   (1 << PLL_SSCG1_MOD_PD_SSCGCLK_N_P)
#define PLL_SSCG1_DITHER												   (1 << PLL_SSCG1_DITHER_P)
#define PLL_SSCG1_MD_REQ												   (1 << PLL_SSCG1_MD_REQ_P)

// PLL NDEC reg
#define PLL_NDEC_VAL_SET(value)						(((unsigned long) (value) << PLL_NDEC_VAL_P) & PLL_NDEC_VAL_M)
#define PLL_NDEC_NREQ_P										10
#define PLL_NDEC_NREQ											(1 << PLL_NDEC_NREQ_P)

// PLL PDEC reg
#define PLL_PDEC_VAL_SET(value)						(((unsigned long) (value) << PLL_PDEC_VAL_P) & PLL_PDEC_VAL_M)
#define PLL_PDEC_PREQ_P										7
#define PLL_PDEC_PREQ											(1 << PLL_PDEC_PREQ_P)

// SSCG control[0]
#define PLL_SSCG0_MDEC_VAL_SET(value)		 (((unsigned long) (value) << PLL_SSCG0_MDEC_VAL_P) & PLL_SSCG0_MDEC_VAL_M)
#define PLL_SSCG0_MREQ_P					 17
#define PLL_SSCG0_MREQ						 (1 << PLL_SSCG0_MREQ_P)
#define PLL_SSCG0_SEL_EXT_SSCG_N_P			 18
#define PLL_SSCG0_SEL_EXT_SSCG_N			 (1 << PLL_SSCG0_SEL_EXT_SSCG_N_P)

// SSCG control[1]
#define PLL_SSCG1_MD_FRACT_P										0
#define PLL_SSCG1_MD_INT_P											11
#define PLL_SSCG1_MF_P												20
#define PLL_SSCG1_MC_P												26
#define PLL_SSCG1_MR_P												23

#define PLL_SSCG1_MD_FRACT_M										(0x7FFUL << PLL_SSCG1_MD_FRACT_P)
#define PLL_SSCG1_MD_INT_M											(0xFFUL << PLL_SSCG1_MD_INT_P)
#define PLL_SSCG1_MF_M												(0x7UL << PLL_SSCG1_MF_P)
#define PLL_SSCG1_MC_M												(0x3UL << PLL_SSCG1_MC_P)
#define PLL_SSCG1_MR_M												(0x7UL << PLL_SSCG1_MR_P)

#define PLL_SSCG1_MD_FRACT_SET(value)								(((unsigned long) (value) << \
																	  PLL_SSCG1_MD_FRACT_P) & PLL_SSCG1_MD_FRACT_M)
#define PLL_SSCG1_MD_INT_SET(value)									(((unsigned long) (value) << \
																	  PLL_SSCG1_MD_INT_P)	& PLL_SSCG1_MD_INT_M)

// Middle of the range values for spread-spectrum
#define PLL0_SSCG_MF_FREQ_VALUE		4
#define PLL0_SSCG_MC_COMP_VALUE		2
#define PLL0_SSCG_MR_DEPTH_VALUE	4
#define PLL0_SSCG_DITHER_VALUE		0

#define PLL_MAX_N_DIV		0x100

